<html>
<head>
  <script src="OLLoader.js"></script>
  <script type="text/javascript">
    function test_Handler_constructor(t) {
        t.plan(4);
        var map = new OpenLayers.Map('map');
        var control = new OpenLayers.Control();
        map.addControl(control);
    
        var callbacks = {foo: "bar"};
        var options = {bar: "foo"};
        var handler = new OpenLayers.Handler(control, callbacks, options);
        t.ok(handler instanceof OpenLayers.Handler,
             "new OpenLayers.Handler returns object");
        t.eq(handler.map.id, map.id,
             "constructing a handler with a map sets the map on the handler");
        t.eq(handler.callbacks.foo, callbacks.foo,
             "constructor correctly sets callbacks");
        t.eq(handler.bar, options.bar,
             "constructor correctly extends handler with options");
    }
    
    function test_Handler_activate(t) {
        t.plan(52);
        var map = new OpenLayers.Map('map');
        var control = new OpenLayers.Control();
        map.addControl(control);
    
        var events = ["mouseover", "mouseout", "mousedown",
                      "mouseup", "mousemove", "click",
                      "dblclick", "resize", "focus", "blur"];

        var handler = new OpenLayers.Handler(control);
        handler.active = true;
        var activated = handler.activate();
        t.ok(!activated,
             "activate returns false if the handler is already active");

        handler.active = false;
        map.events.registerPriority = function(type, obj, func) {
            var r = func();
            if(typeof r == "string") {
                // this is one of the mock handler methods
                t.ok(OpenLayers.Util.indexOf(events, type) > -1,
                     "activate calls registerPriority with browser event: " + type);
                t.eq(typeof func, "function",
                     "activate calls registerPriority with a function");
                t.eq(r, type,
                     "activate calls registerPriority with the correct method");
                t.eq(obj["CLASS_NAME"], "OpenLayers.Handler",
                     "activate calls registerPriority with the handler");
            } else {
                // this is the call with handler.setEvent as the func
                t.ok(r, "activate calls registerPriority with handler.setEvent");
            }
        }
        
        // set browser event like properties on the handler
        for(var i=0; i<events.length; ++i) {
            setMethod(events[i]);
        }
        function setMethod(key) {
            handler[key] = function() {return key};
        }
        activated = handler.activate();
        t.ok(activated,
             "activated returns true if the handler is not already active");
        
    }
    
    function test_Handler_deactivate(t) {
        t.plan(52);
        var map = new OpenLayers.Map('map', { controls: []});
        // No controls so that we don't get more thingies than we expect
        // when we actually clean up after ourselves: r5891 caused this
        // because we actually destroy things now on the navigation control. 
        var control = new OpenLayers.Control();
        map.addControl(control);
    
        var events = ["mouseover", "mouseout", "mousedown",
                      "mouseup", "mousemove", "click",
                      "dblclick", "resize", "focus", "blur"];

        var handler = new OpenLayers.Handler(control);
        handler.active = false;
        var deactivated = handler.deactivate();
        t.ok(!deactivated,
             "deactivate returns false if the handler is already deactive");

        handler.activate();
        map.events.unregister = function(type, obj, func) {
            var r = func();
            if(typeof r == "string") {
                // this is one of the mock handler methods
                t.ok(OpenLayers.Util.indexOf(events, type) > -1,
                     "deactivate calls unregister with browser event: " + type);
                t.eq(typeof func, "function",
                     "activate calls unregister with a function");
                t.eq(func(), type,
                     "activate calls unregister with the correct method");
                t.eq(obj["CLASS_NAME"], "OpenLayers.Handler",
                     "activate calls unregister with the handler");
            } else {
                // this is the call with handler.setEvent as the func
                t.ok(r, "activate calls registerPriority with handler.setEvent");
            }
        }
        
        // set browser event like properties on the handler
        for(var i=0; i<events.length; ++i) {
            // add in a closure for key
            (function(key) {
                handler[key] = function() {return key};
            })(events[i]);
        }
        deactivated = handler.deactivate();
        t.ok(deactivated,
             "deactivated returns true if the handler is already active");
        map.events.unregister = OpenLayers.Events.prototype.unregister;
        map.destroy();
        
    }
    
    function test_Handler_setEvent(t) {
        t.plan(4);
        var map = new OpenLayers.Map('map');
        var control = new OpenLayers.Control();
        map.addControl(control);
        var handler = new OpenLayers.Handler(control);
        handler.click = function(evt) {
        }
        handler.activate();
        var testEvent = {
            xy: new OpenLayers.Pixel(Math.random(), Math.random()),
            altKey: (Math.random() > 0.5),
            shiftKey: (Math.random() > 0.5),
            ctrlKey: (Math.random() > 0.5)
        }
        map.events.triggerEvent("click", testEvent);
        t.ok(handler.evt.xy.x == testEvent.xy.x &&
             handler.evt.xy.y == testEvent.xy.y,
             "handler.evt has proper xy object");
        t.eq(handler.evt.altKey, testEvent.altKey,
             "handler.evt.altKey correct");
        t.eq(handler.evt.shiftKey, testEvent.shiftKey,
             "handler.evt.shiftKey correct");
        t.eq(handler.evt.ctrlKey, testEvent.ctrlKey,
             "handler.evt.ctrlKey correct");
    }
    
    function test_Handler_destroy(t) {
        t.plan(5);
        var map = new OpenLayers.Map('map');
        var control = new OpenLayers.Control();
        map.addControl(control);
        var handler = new OpenLayers.Handler(control);
        var deactivated = false;
        handler.deactivate = function() {
            deactivated = true;
        };
        t.ok(handler.control,
             "handler has a control prior to destroy");
        t.ok(handler.map,
             "handler has a map prior to destroy");
        handler.destroy();
        t.eq(handler.control, null,
             "hanlder.control is null after destroy");
        t.eq(handler.map, null,
             "handler.map is null after destroy");
        t.ok(deactivated,
             "handler.deactivate is called by destroy");
    }
    
    function test_Handler_checkModifiers(t) {
        t.plan(26);
        var handler = new OpenLayers.Handler({});
        handler.keyMask = null;
        var proceed = handler.checkModifiers({});
        t.ok(proceed,
             "checkModifiers returns true if no keyMask on the handler");
        
        
        /**
         * Test checkModifiers for single keyMask values.  The method should
         *     return true if the corresponding key is associated with the
         *     event.  For example, if evt.shiftKey is true and handler.keyMask
         *     is OpenLayers.Handler.MOD_SHIFT, checkModifiers should return
         *     true.
         */
        var constants = {
            MOD_NONE: null,
            MOD_SHIFT: "shiftKey",
            MOD_CTRL: "ctrlKey",
            MOD_ALT: "altKey"
        }
        var proceed, evt, value, c, k;
        for(c in constants) {
            handler.keyMask = OpenLayers.Handler[c];
            // for this key mask, test all single key possibilities
            for(k in constants) {
                value = constants[k];
                evt = {};
                if(value) {
                    // mimic a key down on an event
                    evt[value] = true;
                }
                proceed = handler.checkModifiers(evt);
                // if k == c, proceed should be true - false otherwise
                t.eq(k == c, proceed,
                     "returns " + proceed + " if keyMask is " + c +
                     " and " + ((value) ? value : "no key") + " is down");
            }
        }

        /**
         * Test checkModifiers for double keyMask values.  The method should
         *     return true if the corresponding key combo is associated with the
         *     event.  For example, if evt.shiftKey is true and handler.keyMask
         *     is OpenLayers.Handler.MOD_SHIFT, checkModifiers should return
         *     true.
         */
        var constants = ["MOD_SHIFT", "MOD_CTRL", "MOD_ALT"];
        var keys = ["shiftKey", "ctrlKey", "altKey"];
        var proceed, evt, c1, c2, k1, k2;
        for(var i=0; i<constants.length-1; ++i) {
            c1 = constants[i];
            for(var j=i+1; j<constants.length; ++j) {
                c2 = constants[j];
                handler.keyMask = OpenLayers.Handler[c1] |
                                  OpenLayers.Handler[c2];
                // for this key mask, test all double key possibilities
                for(var x=0; x<keys.length-1; ++x) {
                    k1 = keys[x];
                    for(var y=x+1; y<keys.length; ++y) {
                        k2 = keys[y];
                        evt = {};
                        evt[k1] = true;
                        evt[k2] = true;
                        proceed = handler.checkModifiers(evt);
                        // if the combo matches, proceed should be true
                        // at this point we know that i != j and x != y
                        t.eq(((i == x) || (i == y)) &&
                             ((j == x) || (j == y)),
                             proceed,
                             "returns " + proceed + " if " + c1 + " | " + c2 +
                             " and " + k1 + " + " + k2 + " is down");
                    }
                }
            }
        }
            
    }


  </script>
</head>
<body>
    <div id="map" style="width: 1024px; height: 512px;"/>
</body>
</html>
